/* 
 * File:   Compressor.h
 * Author: Luis
 *
 * Created on 3 de abril de 2013, 15:42
 */

#ifndef COMPRESSOR_H
#define	COMPRESSOR_H

#include <time.h>
#include "FileHeader.h"
#include "../list/GenericList.h"

enum CompresionMethods{
    nonCompresion = 0,
    deflate = 8
};

class Compressor 
{
public:

    Compressor() : centralDirectoryHeader_(0x02014b50), endOfCentralDirectoryHeader_(0x06054b50)
    {
        fileHeaders_ = new GenericList<FileHeader>();
    }

    /**
     * Build the file header of a file.
     * 
     * @param absolutePath Path of the file
     * @param fileName Name of the file
     * @param compressionMethod Compression method that will be used.
     * @param buffer Buffer when the file header and the content of the file will be save. The buffer 
     * must to be created taking into account the size of the file, the 30 bytes more the file name size
     * that the file header needs.
     * @param bufferSize Size of the buffer.
     */
    void addFile(char *absolutePath, char* fileName, CompresionMethods compressionMethod);
    
    /**
     * Add files from a directory 
     * 
     * @param absolutePath Path of the directory
     * @param fileName Name of the directory
     * @param compressionMethod Compression method that will be user
     */
    void addDirectory(char* absolutePath, char* fileName, CompresionMethods compressionMethod);
    
    /**
     * Return the size of the file headers.
     * 
     * @return Size of the file headers.
     */
    int getHeadersLength();
    
    /**
     * Get the size of the central directory.
     * 
     * @return the size of the central directory
     */
    int getCentralDirectorySize();
    
    /**
     * Ge the size of the zip file.
     * 
     * @return The size of the zip file
     */
    int getZipFileLength();
    
    /**
     * Compress a file or a directory.
     * 
     * @param sourcePath Path of the file
     * @param destinyPath Path of the zip file will be stored
     * @param compressionMethod Compression method that the compressor will be used
     */
    void compress(const char* sourcePath,const char* destinyPath, int compressionMethod);
    
private:

    /**
     * Value for the headers of the files.
     */
    const int centralDirectoryHeader_;
    const int endOfCentralDirectoryHeader_;
    GenericList<FileHeader>* fileHeaders_;
    int headersSize_;
    int fileHeadersNamesLength;
    int fileHeaderExtraFieldLength;
    int offsetOfCentralDirectory_;
    int centralDirectorySize_;
    
    void buildZipFormat(char*& buffer);
    void buildCentralDirectoryFileHeader(FileHeader &fileHeader, int fileHeaderOffset, char*& buffer);
    void buildEndOfCentralDirectory(char*& buffer);
};

#endif	/* COMPRESSOR_H */
